home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / mawk10.zip / MAWK_TES.DAT < prev    next >
Text File  |  1991-10-05  |  3KB  |  108 lines

  1.  
  2. #include  <zmalloc.h>
  3.  
  4. extern unsigned hash() ;
  5.  
  6. /* An array A is a pointer to an array of struct array,
  7.    which is two hash tables in one.  One for strings
  8.    and one for doubles.
  9.  
  10.    each array is of size A_HASH_PRIME.
  11.  
  12.    When an index is deleted via  delete A[i], the
  13.    ANODE is not removed from the hash chain.  A[i].cp
  14.    and A[i].sval are both freed and sval is set NULL.
  15.    This method of deletion simplifies for( i in A ) loops.
  16.  
  17.    On the D_ANODE list, we use real deletion and move to the
  18.    front on access.
  19.  
  20.    Separate nodes (as opposed to one type of node on two lists)
  21.    to
  22.      (1) d1 != d2, but sprintf(A_FMT,d1) == sprintf(A_FMT,d1)
  23.          so two dnodes can point at the same anode.
  24.      (2) Save a little data space(64K PC mentality).
  25.  
  26.    the cost is an extra level of indirection.
  27.  
  28.    Some care is needed so that things like
  29.      A[1] = 2 ; delete A["1"] work .
  30. */
  31.  
  32. #define  _dhash(d)    (((int)(d)&0x7fff)%A_HASH_PRIME)
  33. #define  DHASH(d)     (last_dhash=_dhash(d))
  34. static  unsigned  last_dhash ;
  35.  
  36. /*        switch =======;;;;;;hhhh */
  37.  
  38. static  ANODE *find_by_sval(A, sval, cflag)
  39.   ARRAY  A ;
  40.   STRING *sval ;
  41.   int  cflag ; /* create if on */
  42.    char *s = sval->str ;
  43.    unsigned h = hash(s) % A_HASH_PRIME ;
  44.    register ANODE *p = A[h].link ;
  45.    ANODE *q = 0 ; /* holds first deleted ANODE */
  46.  
  47.    while ( p )
  48.    {
  49.      if ( p->sval )
  50.      { if ( strcmp(s,p->sval->str) == 0 )  return p ; }
  51.      else /* its deleted, mark with q */
  52.      if ( ! q )  q = p ;  
  53.  
  54.      p = p->link ;
  55.    }
  56.  
  57.    /* not there */
  58.    if ( cflag )
  59.    {
  60.        if ( q )  p = q ; /* reuse the deleted node q */
  61.        else
  62.        { p = (ANODE *)zmalloc(sizeof(ANODE)) ;
  63.          p->link = A[h].link ; A[h].link = p ;
  64.        }
  65.  
  66.        p->sval = sval ;
  67.        sval->ref_cnt++ ;
  68.        p->cp = (CELL *) zmalloc(sizeof(CELL)) ;
  69.        p->cp->type = C_NOINIT ;
  70.    }
  71.    return p ;
  72. }
  73.  
  74.  
  75. /* on the D_ANODE list, when we find a node we move it
  76.    to the front of the hash chain */
  77.  
  78. static D_ANODE  *find_by_dval(A, d, cflag)
  79.   ARRAY  A ;
  80.   double d ;
  81.   int cflag ;
  82. {
  83.   unsigned h = DHASH(d) ;
  84.   register D_ANODE *p = A[h].dlink ;
  85.   D_ANODE *q = 0 ; /* trails p for move to front */
  86.   ANODE *ap ;
  87.  
  88.    while ( p )
  89.        if ( p->dval == d )
  90.        { /* found */
  91.          if ( ! p->ap->sval ) /* but it was deleted by string */
  92.          { if ( q )  q->dlink = p->dlink ;
  93.            else A[h].dlink = p->dlink ;
  94.            zfree(p, sizeof(D_ANODE)) ;
  95.            break ; 
  96.          }
  97.          /* found */
  98.          if ( !q )  return  p ; /* already at front */
  99.          else /* delete to put at front */
  100.          { q->dlink = p->dlink ; goto found ; }
  101.        }
  102.        else
  103.        { q = p ; p = p->dlink ; }
  104.  
  105. void (*signal())() ;
  106.  
  107.